# @FileName  :  teacher.py
# @Time      :  2025/7/29 14:27
# @Author    :  Ayanami
# @info      :教师CRUD操作

from typing import Optional, List
from tortoise.exceptions import DoesNotExist, IntegrityError
from tortoise.expressions import Q
# from tortoise.queryset import QuerySet
from app.models.models import Teacher
from app.schemas.teacher import TeacherCreate, TeacherUpdate, TeacherQuery


class TeacherCRUD:
    """教师CRUD操作类"""

    @staticmethod
    async def create(teacher_data: TeacherCreate) -> Teacher:
        """创建教师"""
        try:
            teacher = await Teacher.create(**teacher_data.model_dump())
            await teacher.fetch_related("category")
            return teacher
        except IntegrityError as e:
            if "teacher_id" in str(e):
                raise ValueError("教工号已存在")
            elif "id_card" in str(e):
                raise ValueError("身份证号已存在")
            else:
                raise ValueError("数据完整性错误")

    @staticmethod
    async def get_by_id(teacher_id: int) -> Optional[Teacher]:
        """根据ID获取教师"""
        try:
            return await Teacher.get(id=teacher_id, is_deleted=False).prefetch_related("category")
        except DoesNotExist:
            return None

    @staticmethod
    async def get_by_teacher_id(teacher_id: str) -> Optional[Teacher]:
        """根据教工号获取教师"""
        try:
            return await Teacher.get(teacher_id=teacher_id, is_deleted=False).prefetch_related("category")
        except DoesNotExist:
            return None

    @staticmethod
    async def get_by_id_card(id_card: str) -> Optional[Teacher]:
        """根据身份证号获取教师"""
        try:
            return await Teacher.get(id_card=id_card, is_deleted=False).prefetch_related("category")
        except DoesNotExist:
            return None

    @staticmethod
    async def update(teacher_id: int, teacher_data: TeacherUpdate) -> Optional[Teacher]:
        """更新教师信息"""
        try:
            teacher = await Teacher.get(id=teacher_id, is_deleted=False).prefetch_related("category")
            update_data = teacher_data.model_dump(exclude_unset=True)
            if update_data:
                await teacher.update_from_dict(update_data)
                await teacher.save()
                if 'category_id' in update_data:
                    await teacher.fetch_related("category")
            return teacher
        except DoesNotExist:
            return None
        except IntegrityError as e:
            if "teacher_id" in str(e):
                raise ValueError("教工号已存在")
            elif "id_card" in str(e):
                raise ValueError("身份证号已存在")
            else:
                raise ValueError("数据完整性错误")

    @staticmethod
    async def delete(teacher_id: int) -> bool:
        """删除教师"""
        try:
            teacher = await Teacher.get(id=teacher_id, is_deleted=False)
            teacher.is_deleted = True
            await teacher.save(update_fields=["is_deleted"])
            return True
        except DoesNotExist:
            return False

    @staticmethod
    async def get_list(query: TeacherQuery) -> tuple[List[Teacher], int]:
        """获取教师列表"""
        queryset = Teacher.filter(is_deleted=False).prefetch_related("category")

        # 构建查询条件
        if query.name:
            queryset = queryset.filter(name__icontains=query.name)
        if query.teacher_id:
            queryset = queryset.filter(teacher_id=query.teacher_id)
        if query.specialty:
            queryset = queryset.filter(specialty__icontains=query.specialty)
        if query.category_id:
            queryset = queryset.filter(category=query.category_id)
        if query.level:
            queryset = queryset.filter(level=query.level)

        # 获取总数
        total = await queryset.count()

        # 分页
        teachers = await queryset.offset(query.skip).limit(query.limit).order_by('-created_at')

        return teachers, total

    @staticmethod
    async def increment_sessions_count(teacher_id: int) -> bool:
        """增加授课场次"""
        try:
            teacher = await Teacher.get(id=teacher_id, is_deleted=False)
            teacher.sessions_count += 1
            await teacher.save()
            return True
        except DoesNotExist:
            return False

    @staticmethod
    async def get_teachers_by_category(category: int) -> List[Teacher]:
        """根据分类获取教师列表"""
        return await Teacher.filter(category=category, is_deleted=False).prefetch_related("category").order_by('name')

    @staticmethod
    async def search_teachers(keyword: str, limit: int = 10) -> List[Teacher]:
        """搜索教师（姓名、教工号、教学方向）"""
        return await Teacher.filter(
            Q(name__icontains=keyword, is_deleted=False) |
            Q(teacher_id__icontains=keyword, is_deleted=False) |
            Q(specialty__icontains=keyword, is_deleted=False)
        ).prefetch_related("category").limit(limit).order_by('name')


# 创建CRUD实例
teacher_crud = TeacherCRUD()